package com.spi.soconversion.orders;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.spi.soconversion.base.MarshallingException;
import com.spi.soconversion.base.definition.ChildLine;
import com.spi.soconversion.base.definition.DerivedFrom;
import com.spi.soconversion.base.definition.HeaderCharge;
import com.spi.soconversion.base.definition.HeaderTax;
import com.spi.soconversion.base.definition.Item;
import com.spi.soconversion.base.definition.LineCharge;
import com.spi.soconversion.base.definition.LinePriceInfo;
import com.spi.soconversion.base.definition.LineTax;
import com.spi.soconversion.base.definition.OpenSalesOrderDefinition;
import com.spi.soconversion.base.definition.OrderLine;
import com.spi.soconversion.base.definition.OrderLineExtension;
import com.spi.soconversion.base.definition.OrderLineOption;
import com.spi.soconversion.base.definition.OrderLineRelationShip;
import com.spi.soconversion.base.definition.ParentLine;
import com.spi.soconversion.base.definition.PersonInfo;
import com.spi.soconversion.base.definition.ProductLine;
import com.spi.soconversion.base.definition.ProductServiceAssoc;
import com.spi.soconversion.base.definition.ServiceLine;

//--------------------------------------------------------------------------------------------------
/**
 * This class is to marshall the java object into a order XML files required for open orders in
 * sales order conversion.
 * 
 * @author XSPID41
 * 
 * The following is the XML hierarchy.
 * 
 * Order
 *  |->Extn
 *  |->OrderLines
 *  	|->OrderLine
 *  		|->Extn
 *  		|->OrderLineOptions
 *  			|->OrderLineOption
 *  		|->Item
 *  		|->PersonInfoShipTo
 *  		|->LinePriceInfo
 *  		|->LineCharges
 *  			|->LineCharge
 *  		|->LineTaxes
 *  			|->LineTax
 *  |->PersonInfoShipTo
 *  |->PersonInfoBillTo
 *  |->HeaderCharges
 *  	|->HeaderCharge
 *  |->HeaderTaxes
 *  	|->HeaderTax

 *
 */
public class OpenSalesOrderDefinitionMarshaller {

	static private OpenSalesOrderDefinitionMarshaller instance = new OpenSalesOrderDefinitionMarshaller();
	
	//----------------------------------------------------------------------------------------------
    static public OpenSalesOrderDefinitionMarshaller getInstance() {
        return instance;
    }

	//----------------------------------------------------------------------------------------------
    private OpenSalesOrderDefinitionMarshaller() {
    }

	//----------------------------------------------------------------------------------------------
    /**
     * Creates a new order definition writer
     * 
     * @param orderDef
     * @return
     * @throws MarshallingException
     */
    public OrderDefinitionWriter createOrderDefinitionWriter(OpenSalesOrderDefinition orderDef)
    throws MarshallingException {
        OrderDefinitionWriter writer = new OrderDefinitionWriter(orderDef);
        return writer;
    }

	//----------------------------------------------------------------------------------------------
    /**
     * Writes a order definition object into an DOM document
     * 
     * @param orderDef
     * @return
     * @throws MarshallingException
     */
    public Document writeOrderDefinition(OpenSalesOrderDefinition orderDef) 
    throws MarshallingException {
        Document result = null;
        OrderDefinitionWriter writer = createOrderDefinitionWriter(orderDef);
        writer.marshall();
        result = writer.getDocument();
        return result;
    }
}

//--------------------------------------------------------------------------------------------------
/**
 * This class writes the generated order definition into an order XML file.
 * 
 * @author XSPID41
 *
 */
class OrderDefinitionWriter implements Constants {

	private Document document = null;
    private OpenSalesOrderDefinition orderDef = null;
    
	//----------------------------------------------------------------------------------------------
    /**
     * To instantiate a writer for order definition
     * 
     * @param orderDef
     * @throws MarshallingException
     */
    protected OrderDefinitionWriter(OpenSalesOrderDefinition orderDef)
	throws MarshallingException {
        try {
            this.orderDef = orderDef;
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            document = db.newDocument();
        } 
        catch (ParserConfigurationException pce) {
            throw new MarshallingException(pce);
        }
    }

	//----------------------------------------------------------------------------------------------
    /**
     * Get the DOM document for XML
     * 
     * @return Document
     */
    public Document getDocument() {
        return document;
    }
    
	//----------------------------------------------------------------------------------------------
    /**
     * Marshall the OrderDefinition element into Order XML files for open orders.
     * 
     * @throws MarshallingException
     */
    public void marshall()
	throws MarshallingException {
    	
    	// create order
        Element orderElement = document.createElement(ORDER_ELEMENT);
        orderElement.setAttribute(BILL_TO_ID_ATTRIBUTE, orderDef.getBillToID());
        orderElement.setAttribute(BILL_TO_KEY_ATTRIBUTE, orderDef.getBillToKey());
        orderElement.setAttribute(DOCUMENT_TYPE_ATTRIBUTE, orderDef.getDocumentType());
        orderElement.setAttribute(ENTERPRISE_CODE_ATTRIBUTE, orderDef.getEnterpriseCode());
        orderElement.setAttribute(ENTRY_TYPE_ATTRIBUTE, orderDef.getEntryType());
        orderElement.setAttribute(ORDER_DATE_ATTRIBUTE, orderDef.getOrderDate());
        orderElement.setAttribute(ORDER_NO_ATTRIBUTE, orderDef.getOrderNo());
        orderElement.setAttribute(PAYMENT_STATUS_ATTRIBUTE, orderDef.getPaymentStatus());
        orderElement.setAttribute(ORDER_NAME_ATTRIBUTE, orderDef.getOrderName());
        orderElement.setAttribute(SELLER_ORGANIZATION_CODE_ATTRIBUTE, orderDef.getSellerOrganizationCode());
        orderElement.setAttribute(SHIP_TO_ID_ATTRIBUTE, orderDef.getShipToID());
        orderElement.setAttribute(SHIP_TO_KEY_ATTRIBUTE, orderDef.getShipToKey());
        orderElement.setAttribute(TAX_EXEMPT_FLAG_ATTRIBUTE, orderDef.getTaxExemptFlag());
        orderElement.setAttribute(TAX_EXEMPTION_CERTIFICATE_ATTRIBUTE, orderDef.getTaxExemptCertificate());
        document.appendChild(orderElement);
        
        // create order extn
        Element orderExtnElement = document.createElement(ORDER_EXTN_ELEMENT);
        orderExtnElement.setAttribute(EXTN_IS_DEPOSIT_AMOUNT_COLLECTED_ATTRIBUTE, 
												orderDef.getOrderExtn().getExtnIsDepositAmountCollected());
        orderExtnElement.setAttribute(EXTN_DEPOSIT_AMOUNT_ATTRIBUTE, 
        										orderDef.getOrderExtn().getExtnDepositAmount());
        orderExtnElement.setAttribute(EXTN_HBC_ASSOCIATE_ID_ATTRIBUTE, 
        										orderDef.getOrderExtn().getExtnHBCAssociateID());
        orderExtnElement.setAttribute(EXTN_AMOUNT_COLLECTED_ATTRIBUTE, 
												orderDef.getOrderExtn().getExtnAmountCollected());        
        orderExtnElement.setAttribute(EXTN_DEPOSIT_FLAG_ATTRIBUTE,
        										orderDef.getOrderExtn().getExtnDepositFlag());
        orderExtnElement.setAttribute(EXTN_GIFT_REGISTRY_NUM_ATTRIBUTE, orderDef.getOrderExtn().getExtnGiftRegistryNum());
        orderElement.appendChild(orderExtnElement);

        // create header charges
        HeaderCharge[] headerChargeArray = orderDef.getHeaderChargeArray();
        if (headerChargeArray.length > 0) {
	        Element headerChargesElement = document.createElement(HEADER_CHARGES_ELEMENT);        
	        for (int i = 0; i < headerChargeArray.length; i++) {
	            createHeaderChargeElement(headerChargesElement, headerChargeArray[i]);
	        }
	        orderElement.appendChild(headerChargesElement);
        }
        
        // create header taxes
        HeaderTax[] headerTaxArray = orderDef.getHeaderTaxArray();
        if (headerTaxArray.length > 0) {
	        Element headerTaxesElement = document.createElement(HEADER_TAXES_ELEMENT);        
	        for (int i = 0; i < headerTaxArray.length; i++) {
	            createHeaderTaxElement(headerTaxesElement, headerTaxArray[i]);
	        }
	        orderElement.appendChild(headerTaxesElement);
        }

        // create order lines
        OrderLine[] orderLineArray = orderDef.getOrderLineArray();
        if (orderLineArray.length > 0) {
	        Element orderLinesElement = document.createElement(ORDER_LINES_ELEMENT);        
	        for (int i = 0; i < orderLineArray.length; i++) {
	            createOrderLineElement(orderLinesElement, orderLineArray[i]);
	        }
	        orderElement.appendChild(orderLinesElement);
        }
                
//        // create person info ship to
//        Element personInfoShipToElement = document.createElement(PERSON_INFO_SHIP_TO_ELEMENT);        
//        orderElement.appendChild(createPersonInfoElement(personInfoShipToElement, orderDef, 
//        													Constants.PERSON_INFO_SHIP_TO_ELEMENT));
//        
//        // create person info bill to
//        Element personInfoBillToElement = document.createElement(PERSON_INFO_BILL_TO_ELEMENT);
//        orderElement.appendChild(createPersonInfoElement(personInfoBillToElement, orderDef, 
//        													Constants.PERSON_INFO_BILL_TO_ELEMENT));
        
        // create product service assocs
        ProductServiceAssoc[] productServiceAssocArray = orderDef.getProductServiceAssocArray();
        if (productServiceAssocArray.length > 0) {
	        Element productServiceAssocsElement = document.createElement(PRODUCT_SERVICE_LINE_ASSOCS_ELEMENT);
	        for (int i = 0; i < productServiceAssocArray.length; i++) {
	            createProductServiceAssocElement(productServiceAssocsElement, productServiceAssocArray[i]);
	        }
	        orderElement.appendChild(productServiceAssocsElement);
        }
        
        // create order line relationships
        OrderLineRelationShip[] orderLineRelationShipArray = orderDef.getOrderLineRelationshipArray();
	        if (orderLineRelationShipArray.length > 0) {
	        Element orderLineRelationshipsElement = document.createElement(ORDER_LINE_RELATIONSHIPS_ELEMENT);
	        for (int i = 0; i < orderLineRelationShipArray.length; i++) {
	            createOrderLineRelationshipElement(orderLineRelationshipsElement, orderLineRelationShipArray[i]);
	        }
	        orderElement.appendChild(orderLineRelationshipsElement);
        }
    }
    
	//----------------------------------------------------------------------------------------------
    /**
     * Generate a ShipTo or BillTo person information
     * 
     * @param orderLinesElement
     * @param personInfoShipTo
     */
    public Element createPersonInfoElement(Element personInfoElement, OpenSalesOrderDefinition orderDef, String type) {                       
        PersonInfo personInfo = null;
        if (Constants.PERSON_INFO_SHIP_TO_ELEMENT.equals(type)) {
        	personInfo = orderDef.getPersonInfoShipTo();
        } else if (Constants.PERSON_INFO_BILL_TO_ELEMENT.equals(type)) {
        	personInfo = orderDef.getPersonInfoBillTo();
        }
        personInfoElement.setAttribute(ADDRESS_LINE_1_ATTRIBUTE, personInfo.getAddressLine1());
        personInfoElement.setAttribute(ADDRESS_LINE_2_ATTRIBUTE, personInfo.getAddressLine2());
        personInfoElement.setAttribute(ADDRESS_LINE_3_ATTRIBUTE, personInfo.getAddressLine3());
        personInfoElement.setAttribute(ADDRESS_LINE_4_ATTRIBUTE, personInfo.getAddressLine4());
        personInfoElement.setAttribute(ADDRESS_LINE_5_ATTRIBUTE, personInfo.getAddressLine5());
        personInfoElement.setAttribute(ADDRESS_LINE_6_ATTRIBUTE, personInfo.getAddressLine6());
        personInfoElement.setAttribute(CITY_ATTRIBUTE, personInfo.getCity());
        personInfoElement.setAttribute(COUNTRY_ATTRIBUTE, personInfo.getCountry());        		
        personInfoElement.setAttribute(DAY_PHONE_ATTRIBUTE, personInfo.getDayPhone());
        personInfoElement.setAttribute(EMAIL_ID_ATTRIBUTE, personInfo.getEmailID());
        personInfoElement.setAttribute(EVENING_FAX_NO_ATTRIBUTE, personInfo.getEveningFaxNo());
        personInfoElement.setAttribute(EVENING_PHONE_ATTRIBUTE, personInfo.getEveningPhone());
        personInfoElement.setAttribute(FIRST_NAME_ATTRIBUTE, personInfo.getFirstName());
        personInfoElement.setAttribute(LAST_NAME_ATTRIBUTE, personInfo.getLastName());
        personInfoElement.setAttribute(MIDDLE_NAME_ATTRIBUTE, personInfo.getMiddleName());
        personInfoElement.setAttribute(MOBILE_PHONE_ATTRIBUTE, personInfo.getMobilePhone());
        personInfoElement.setAttribute(OTHER_PHONE_ATTRIBUTE, personInfo.getOtherPhone());
        personInfoElement.setAttribute(STATE_ATTRIBUTE, personInfo.getState());
        personInfoElement.setAttribute(TITLE_ATTRIBUTE, personInfo.getTitle());
        personInfoElement.setAttribute(ZIP_CODE_ATTRIBUTE, personInfo.getZipCode());        		
        return personInfoElement;
    }

	//----------------------------------------------------------------------------------------------
    /**
     * Generate <OrderLine> elements for <OrderLines> element
     * 
     * @param orderDefElement
     * @param orderLine
     */
    public void createOrderLineElement(Element orderLinesElement, OrderLine orderLine) {
    	Element orderLineElement = document.createElement(ORDER_LINE_ELEMENT);
    	orderLineElement.setAttribute(DELIVERY_METHOD_ATTRIBUTE, orderLine.getDeliveryMethod());
    	orderLineElement.setAttribute(FULFILLMENT_TYPE_ATTRIBUTE, orderLine.getFullfillmentType());
    	orderLineElement.setAttribute(ITEM_GROUP_CODE_ATTRIBUTE, orderLine.getItemGroupCode());
    	orderLineElement.setAttribute(LINE_TYPE_ATTRIBUTE, orderLine.getLineType());
    	orderLineElement.setAttribute(LINE_STATUS_ATTRIBUTE, orderLine.getLineStatus());
    	orderLineElement.setAttribute(ORDER_QTY_ATTRIBUTE, orderLine.getOrderedQty());
    	orderLineElement.setAttribute(PRIME_LINE_NO_ATTRIBUTE, orderLine.getPrimeLineNo());
    	orderLineElement.setAttribute(PROMISED_APPT_START_DATE, orderLine.getPromisedApptStartDate());
    	orderLineElement.setAttribute(PROMISED_APPT_END_DATE, orderLine.getPromisedApptEndDate());
    	orderLineElement.setAttribute(REQ_DELIVERY_DATE_ATTRIBUTE, orderLine.getReqDeliveryDate());
    	orderLineElement.setAttribute(SHIP_NODE_ATTRIBUTE, orderLine.getShipNode());
    	orderLineElement.setAttribute(SHIP_TO_ID_ATTRIBUTE, orderLine.getShipToId());
    	orderLineElement.setAttribute(SUB_LINE_NO_ATTRIBUTE, orderLine.getSubLineNo());
    	orderLineElement.setAttribute(IS_PRICE_LOCKED_ATTRIBUTE, orderLine.getPriceLocked());
    	orderLineElement.setAttribute(PICKABLE_FLAG_ATTRIBUTE, orderLine.getPickableFlag());
    	orderLineElement.setAttribute(REQ_SHIP_DATE_ATTRIBUTE, orderLine.getReqShipDate());
    	orderLineElement.setAttribute(SHIP_TO_KEY_ATTRIBUTE, orderLine.getShipToKey());
    			
    	// create order extn
    	createOrderLineExtnElement(orderLineElement, orderLine.getOrderLineExtension());
    	
    	// create derived from
    	if (orderLine.getDerivedFrom() != null) {
    		createDerivedFromElement(orderLineElement, orderLine.getDerivedFrom());
    	}	
    	
    	// create order line options    	
        OrderLineOption[] orderLineOptionArray = orderLine.getOrderLineOptionArray();
        if (orderLineOptionArray.length > 0) {
	    	Element orderLineOptionsElement = document.createElement(ORDER_LINE_OPTIONS_ELEMENT);
	        for (int i = 0; i < orderLineOptionArray.length; i++) {
	        	createOrderLineOptionElement(orderLineOptionsElement, orderLineOptionArray[i]);
	        }
	        orderLineElement.appendChild(orderLineOptionsElement);
        }
    	
    	// create item
    	createItemElement(orderLineElement, orderLine.getItem());
    	    	    	
    	// create person info ship
//    	Element personInfoElement = document.createElement(PERSON_INFO_SHIP_TO_ELEMENT);
//    	createPersonInfoElement(personInfoElement, orderDef, Constants.PERSON_INFO_SHIP_TO_ELEMENT);
//    	orderLineElement.appendChild(personInfoElement);
    	
    	// create line price info
    	createLinePriceInfoElement(orderLineElement, orderLine.getLinePriceInfo());
    	
    	// create line charges  
    	LineCharge[] lineChargeArray = orderLine.getLineChargeArray();
    	if (lineChargeArray.length > 0) {
	    	Element lineChargesElement = document.createElement(LINE_CHARGES_ELEMENT);
	        for (int j = 0; j < lineChargeArray.length; j++) {
	        	createLineChargeElement(lineChargesElement, lineChargeArray[j]);
	        }    		
	    	orderLineElement.appendChild(lineChargesElement);
    	}
               
    	// create line taxes
        LineTax[] lineTaxArray = orderLine.getLineTaxArray();
        if (lineTaxArray.length > 0) {
	        Element lineTaxesElement = document.createElement(LINE_TAXES_ELEMENT);   	    
	        for (int i = 0; i < lineTaxArray.length; i++) {
	        	createLineTaxElement(lineTaxesElement, lineTaxArray[i]);
	        }
	        orderLineElement.appendChild(lineTaxesElement);    	
        }
        
    	orderLinesElement.appendChild(orderLineElement);    	
    }

	//----------------------------------------------------------------------------------------------
    /**
     * Generate <Extn> element for Order Lines
     * 
     * @param orderLinesElement
     * @param orderLineExtn
     */
    public void createOrderLineExtnElement(Element orderLineElement, OrderLineExtension orderLineExtn) {
    	Element orderLineExtnElement = document.createElement(ORDER_LINE_EXTN_ELEMENT);
    	orderLineExtnElement.setAttribute(EXTN_AMOUNT_COLLECTED_ATTRIBUTE, orderLineExtn.getExtnAmountCollected());
    	orderLineExtnElement.setAttribute(EXTN_GIFT_REGISTRY_NO_ATTRIBUTE, orderLineExtn.getExtnGiftRegistryNo());   
    	orderLineExtnElement.setAttribute(EXTN_GIFT_REGISTRY_LINE_NO_ATTRIBUTE, orderLineExtn.getExtnGiftRegistryLineNo());    
    	orderLineExtnElement.setAttribute(EXTN_POS_ELIGIBLE_ATTRIBUTE, orderLineExtn.getExtnPOSEligible());
    	orderLineExtnElement.setAttribute(EXTN_POS_TXN_NUM_ATTRIBUTE, orderLineExtn.getExtnPOSTxnNum());    
    	orderLineExtnElement.setAttribute(EXTN_POS_STORE_NUM_ATTRIBUTE, orderLineExtn.getExtnPOSStoreNum());    
    	orderLineExtnElement.setAttribute(EXTN_POS_REG_NUM_ATTRIBUTE, orderLineExtn.getExtnPOSRegNum());    
    	orderLineExtnElement.setAttribute(EXTN_POS_PROVINCE_ATTRIBUTE, orderLineExtn.getExtnPOSProvince());    
    	orderLineExtnElement.setAttribute(EXTN_TAX_PROVINCE_ATTRIBUTE, orderLineExtn.getExtnTaxProvince());   
    	orderLineExtnElement.setAttribute(EXTN_POS_TENDER_DT_ATTRIBUTE, orderLineExtn.getExtnPOSTenderDT());    
    	orderLineExtnElement.setAttribute(EXTN_RESTOCKING_FEE_FLAG_ATTRIBUTE, orderLineExtn.getExtnRestockingFeeFlag());    
    	orderLineExtnElement.setAttribute(EXTN_DC_DROP_OFF_FLAG_ATTRIBUTE, orderLineExtn.getExtnDCdropoffFlag());    
    	orderLineExtnElement.setAttribute(EXTN_WARRANTY_SKU_ATTRIBUTE, orderLineExtn.getExtnWarrantySKU());    
    	orderLineExtnElement.setAttribute(EXTN_IS_VENDOR_MODEL_ITEM_ATTRIBUTE, orderLineExtn.getExtnIsVendorModelItem());    
    	orderLineExtnElement.setAttribute(EXTN_POND_ID_ATTRIBUTE, orderLineExtn.getExtnPondID());    
    	orderLineExtnElement.setAttribute(EXTN_IS_POND_ATTRIBUTE, orderLineExtn.getExtnIsPond());   
    	orderLineExtnElement.setAttribute(EXTN_SWING_BY_STORE_ATTRIBUTE, orderLineExtn.getExtnSwingByStore());   
    	orderLineExtnElement.setAttribute(EXTN_IS_OPEN_BOX_ITEM_ATTRIBUTE, orderLineExtn.getExtnIsOpenBoxItem());    
    	orderLineExtnElement.setAttribute(EXTN_IS_SWING_BY_ATTRIBUTE, orderLineExtn.getExtnIsSwingBy());
        orderLineElement.appendChild(orderLineExtnElement);
    }
    
    
    public void createDerivedFromElement(Element orderLineElement, DerivedFrom derivedFrom) {
    	Element derivedFromElement = document.createElement(DERIVED_FROM_ELEMENT);
    	derivedFromElement.setAttribute(DERIVED_FROM_DOCUMENT_TYPE_ATTRIBUTE, derivedFrom.getDocumentType());
    	derivedFromElement.setAttribute(DERIVED_FROM_ENTERPRISE_CODE_ATTRIBUTE, derivedFrom.getEnterpriseCode());
    	derivedFromElement.setAttribute(ORDER_NO_ATTRIBUTE, derivedFrom.getOrderNo());
    	derivedFromElement.setAttribute(DERIVED_FROM_PRIME_LINE_NO_ATTRIBUTE, derivedFrom.getPrimeLineNo());
    	derivedFromElement.setAttribute(DERIVED_FROM_SUB_LINE_NO_ATTRIBUTE, derivedFrom.getSubLineNo());
        orderLineElement.appendChild(derivedFromElement);
    }
    
	//----------------------------------------------------------------------------------------------
    /**
     * Generate <OrderLineOption> element
     * 
     * @param orderLinesElement
     * @param orderLineOptions
     */
    public void createOrderLineOptionElement(Element orderLineOptionsElement, OrderLineOption orderLineOption) {
    	Element orderLineOptionElement = document.createElement(ORDER_LINE_OPTION_ELEMENT);
    	orderLineOptionElement.setAttribute(OPTION_DESCRIPTION_ATTRIBUTE, orderLineOption.getOptionDescription());
    	orderLineOptionElement.setAttribute(OPTION_ITEM_ID_ATTRIBUTE, orderLineOption.getOptionItemId());
    	orderLineOptionElement.setAttribute(OPTION_UOM_ATTRIBUTE, orderLineOption.getOptionUOM());
    	orderLineOptionElement.setAttribute(UNIT_PRICE_ATTRIBUTE, orderLineOption.getUnitPrice());
    	orderLineOptionsElement.appendChild(orderLineOptionElement);    	
    }
    
	//----------------------------------------------------------------------------------------------
    /**
     * Generate <Item> element
     * 
     * @param orderLinesElement
     * @param item
     */
    public void createItemElement(Element orderLineElement, Item item) {
    	Element itemElement = document.createElement(ITEM_ELEMENT);
    	itemElement.setAttribute(ITEM_DESC_ATTRIBUTE, item.getItemDescription());
    	itemElement.setAttribute(ITEM_ID_ATTRIBUTE, item.getItemID());
    	itemElement.setAttribute(ITEM_SHORT_DESC_ATTRIBUTE, item.getItemShortDesc());
    	itemElement.setAttribute(PRODUCT_CLASS_ATTRIBUTE, item.getProductClass());
    	itemElement.setAttribute(UNIT_COST_ATTRIBUTE, item.getUnitCost());
    	itemElement.setAttribute(UNIT_OF_MEASURE_ATTRIBUTE, item.getUnitOfMeasure());
    	itemElement.setAttribute(ITEM_WEIGHT_ATTRIBUTE, item.getItemWeight());
    	itemElement.setAttribute(ITEM_WEIGHT_UOM_ATTRIBUTE, item.getItemWeightUOM());
    	itemElement.setAttribute(PRODUCT_LINE_ATTRIBUTE, item.getProductLine());
    	orderLineElement.appendChild(itemElement);
    }
    
	//----------------------------------------------------------------------------------------------
    /**
     * Generate <LinePriceInfo> element
     * 
     * @param orderLineElement
     * @param linePriceInfo
     */
    public void createLinePriceInfoElement(Element orderLineElement, LinePriceInfo linePriceInfo) {
    	Element linePriceInfoElement = document.createElement(LINE_PRICE_INFO_ELEMENT);
    	linePriceInfoElement.setAttribute(TAX_EXEMPTION_CERTIFICATE_ATTRIBUTE, linePriceInfo.getTaxExemptionCertificate());
    	linePriceInfoElement.setAttribute(TAXABLE_FLAG_ATTRIBUTE, linePriceInfo.getTaxableFlag());
    	linePriceInfoElement.setAttribute(UNIT_PRICE_ATTRIBUTE, linePriceInfo.getUnitPrice());    	
    	orderLineElement.appendChild(linePriceInfoElement);
    }
    
	//----------------------------------------------------------------------------------------------
    /**
     * Generate <LineCharge> elements for <LineCharges> element
     * 
     * @param orderLineElement
     * @param lineCharges
     */
    public void createLineChargeElement(Element lineChargesElement, LineCharge lineCharge) {
    	Element lineChargeElement = document.createElement(LINE_CHARGE_ELEMENT);
    	lineChargeElement.setAttribute(CHARGE_CATEGORY_ATTRIBUTE, lineCharge.getChargeCategory());
    	lineChargeElement.setAttribute(CHARGE_NAME_ATTRIBUTE, lineCharge.getChargeName());
    	lineChargeElement.setAttribute(CHARGE_PER_LINE_ATTRIBUTE, lineCharge.getChargePerLine().toString());
    	lineChargeElement.setAttribute(CHARGE_PER_UNIT_ATTRIBUTE, lineCharge.getChargePerUnit());
    	lineChargesElement.appendChild(lineChargeElement);
    }
    
	//----------------------------------------------------------------------------------------------
    /**
     * Generate <LineTax> elements for <LineTaxes> element
     * 
     * @param orderLineElement
     * @param lineTaxes
     */
    public void createLineTaxElement(Element lineTaxesElement, LineTax lineTax) {
    	Element lineTaxElement = document.createElement(LINE_TAX_ELEMENT);
    	lineTaxElement.setAttribute(CHARGE_CATEGORY_ATTRIBUTE, lineTax.getChargeCategory());
    	lineTaxElement.setAttribute(CHARGE_NAME_ATTRIBUTE, lineTax.getChargeName());
    	lineTaxElement.setAttribute(TAX_ATTRIBUTE, lineTax.getTax().toString());
    	lineTaxElement.setAttribute(TAX_NAME_ATTRIBUTE, lineTax.getTaxName());
    	lineTaxElement.setAttribute(TAX_PERCENTAGE_ATTRIBUTE, lineTax.getTaxPercentage());
    	lineTaxElement.setAttribute(TAXABLE_FLAG_ATTRIBUTE, lineTax.getTaxableFlag());
    	lineTaxesElement.appendChild(lineTaxElement);
    }

	//----------------------------------------------------------------------------------------------
    /**
     * 
     */
    public void createProductServiceAssocElement(Element productServiceAssocsElement, 
    		ProductServiceAssoc productServiceAssoc) {
    	Element productServiceAssocElement = document.createElement(PRODUCT_SERIVCE_LINE_ASSOC_ELEMENT);
    	productServiceAssocElement.setAttribute(PRODUCT_LINE_ATTRIBUTE, productServiceAssoc.getProductLineAttr());
    	createProductLineElement(productServiceAssocElement, productServiceAssoc.getProductLine());
    	createServiceLineElement(productServiceAssocElement, productServiceAssoc.getServiceLine());
    	productServiceAssocsElement.appendChild(productServiceAssocElement);    	
    }

	//----------------------------------------------------------------------------------------------
    /**
     * 
     */
    public void createProductLineElement(Element productServiceAssocElement, 
    		ProductLine productLine) {
    	Element productLineElement = document.createElement(PRODUCT_LINE_ELEMENT);
    	productLineElement.setAttribute(PRIME_LINE_NO_ATTRIBUTE, productLine.getPrimeLineNo());
    	productLineElement.setAttribute(SUB_LINE_NO_ATTRIBUTE, productLine.getSubLineNo());
    	productServiceAssocElement.appendChild(productLineElement);    	
    }

	//----------------------------------------------------------------------------------------------
    /**
     * 
     */
    public void createServiceLineElement(Element productServiceAssocElement, 
    		ServiceLine serviceLine) {
    	Element serviceLineElement = document.createElement(SERVICE_LINE_ELEMENT);
    	serviceLineElement.setAttribute(PRIME_LINE_NO_ATTRIBUTE, serviceLine.getPrimeLineNo());
    	serviceLineElement.setAttribute(SUB_LINE_NO_ATTRIBUTE, serviceLine.getSubLineNo());
    	productServiceAssocElement.appendChild(serviceLineElement);    	
    }

	//----------------------------------------------------------------------------------------------
    /**
     * 
     */
    public void createOrderLineRelationshipElement(Element orderLineRelationshipsElement, 
    		OrderLineRelationShip orderLineRelationShip) {
    	Element orderLineRelationshipElement = document.createElement(ORDER_LINE_RELATIONSHIP_ELEMENT);
    	orderLineRelationshipElement.setAttribute(RELATION_SHIP_TYPE_ATTRIBUTE, orderLineRelationShip.getRelationShipType());
    	createParentLineElement(orderLineRelationshipElement, orderLineRelationShip.getParentLine());
    	createChildLineElement(orderLineRelationshipElement, orderLineRelationShip.getChildLine());
    	orderLineRelationshipsElement.appendChild(orderLineRelationshipElement);    	
    }

	//----------------------------------------------------------------------------------------------
    /**
     * 
     */
    public void createParentLineElement(Element orderLineRelationshipElement, 
    		ParentLine parentLine) {
    	Element parentLineElement = document.createElement(PARENT_LINE_ELEMENT);
    	parentLineElement.setAttribute(PRIME_LINE_NO_ATTRIBUTE, parentLine.getPrimeLineNo());
    	parentLineElement.setAttribute(SUB_LINE_NO_ATTRIBUTE, parentLine.getSubLineNo());
    	orderLineRelationshipElement.appendChild(parentLineElement);    	
    }

	//----------------------------------------------------------------------------------------------
    /**
     * 
     */
    public void createChildLineElement(Element orderLineRelationshipElement, 
    		ChildLine childLine) {
    	Element childLineElement = document.createElement(CHILD_LINE_ELEMENT);
    	childLineElement.setAttribute(PRIME_LINE_NO_ATTRIBUTE, childLine.getPrimeLineNo());
    	childLineElement.setAttribute(SUB_LINE_NO_ATTRIBUTE, childLine.getSubLineNo());
    	orderLineRelationshipElement.appendChild(childLineElement);    	
    }

	//----------------------------------------------------------------------------------------------
    /**
     * Generate <HeaderCharge> elements for <HeaderCharges> element
     * 
     * @param orderDefElement
     * @param headerCharge
     */
    public void createHeaderChargeElement(Element headerChargesElement, HeaderCharge headerCharge) {
    	Element headerChargeElement = document.createElement(HEADER_CHARGE_ELEMENT);
    	headerChargeElement.setAttribute(CHARGE_AMOUNT_ATTRIBUTE, headerCharge.getChargeAmount().toString());
    	headerChargeElement.setAttribute(CHARGE_CATEGORY_ATTRIBUTE, headerCharge.getChargeCategory());
    	headerChargeElement.setAttribute(CHARGE_NAME_ATTRIBUTE, headerCharge.getChargeName()); 				
    	headerChargesElement.appendChild(headerChargeElement);
    }

	//----------------------------------------------------------------------------------------------
    /**
     * Generate <HeaderTax> elements for <HeaderTaxes> element
     * 
     * @param orderDefElement
     * @param headerTax
     */
    public void createHeaderTaxElement(Element headerTaxesElement, HeaderTax headerTax) {
    	Element headerTaxElement = document.createElement(HEADER_TAX_ELEMENT);
    	headerTaxElement.setAttribute(TAX_ATTRIBUTE, headerTax.getTax().toString());
    	headerTaxElement.setAttribute(TAX_NAME_ATTRIBUTE, headerTax.getTaxName());
    	headerTaxElement.setAttribute(TAX_PERCENTAGE_ATTRIBUTE, headerTax.getTaxPercentage());
    	headerTaxElement.setAttribute(TAXABLE_FLAG_ATTRIBUTE, headerTax.getTaxableFlag());
    	headerTaxesElement.appendChild(headerTaxElement);
    }            
}

//--------------------------------------------------------------------------------------------------
/**
 * Constants for XML elements and attributes.
 * 
 * @author XSPID41
 *
 */
interface Constants {
	
	// ELEMENT
	String ORDER_ELEMENT = "Order";
	String ORDER_EXTN_ELEMENT = "Extn";
	String ORDER_LINES_ELEMENT = "OrderLines";
	String ORDER_LINE_ELEMENT = "OrderLine";
	String ORDER_LINE_EXTN_ELEMENT = "Extn";
	String DERIVED_FROM_ELEMENT = "DerivedFrom";
	String ORDER_LINE_OPTIONS_ELEMENT = "OrderLineOptions";
	String ORDER_LINE_OPTION_ELEMENT = "OrderLineOption";
	String ITEM_ELEMENT = "Item";
	String PERSON_INFO_SHIP_TO_ELEMENT = "PersonInfoShipTo";
	String LINE_PRICE_INFO_ELEMENT = "LinePriceInfo";
	String LINE_CHARGES_ELEMENT = "LineCharges";
	String LINE_CHARGE_ELEMENT = "LineCharge";
	String LINE_TAXES_ELEMENT = "LineTaxes";
	String LINE_TAX_ELEMENT = "LineTax";
	String PERSON_INFO_BILL_TO_ELEMENT = "PersonInfoBillTo";
	String HEADER_CHARGES_ELEMENT = "HeaderCharges";
	String HEADER_CHARGE_ELEMENT = "HeaderCharge";
	String HEADER_TAXES_ELEMENT = "HeaderTaxes";
	String HEADER_TAX_ELEMENT = "HeaderTax";
	String PRODUCT_SERVICE_LINE_ASSOCS_ELEMENT = "ProductServiceAssocs";
	String PRODUCT_SERIVCE_LINE_ASSOC_ELEMENT = "ProductServiceAssoc";
	String PRODUCT_LINE_ELEMENT = "ProductLine";
	String SERVICE_LINE_ELEMENT = "ServiceLine";
	String ORDER_LINE_RELATIONSHIPS_ELEMENT = "OrderLineRelationships";
	String ORDER_LINE_RELATIONSHIP_ELEMENT = "OrderLineRelationship";
	String PARENT_LINE_ELEMENT = "ParentLine";
	String CHILD_LINE_ELEMENT = "ChildLine";
	
	// ATTRIBUTES
	
	// Order Attributes
	String BILL_TO_ID_ATTRIBUTE = "BillToID";
	String BILL_TO_KEY_ATTRIBUTE = "BillToKey";
	String DOCUMENT_TYPE_ATTRIBUTE = "DocumentType";
	String ENTERPRISE_CODE_ATTRIBUTE = "EnterpriseCode";
	String ENTRY_TYPE_ATTRIBUTE = "EntryType";
	String ORDER_DATE_ATTRIBUTE = "OrderDate";
	String ORDER_NO_ATTRIBUTE = "OrderNo";
	String PAYMENT_STATUS_ATTRIBUTE = "PaymentStatus";
	String ORDER_NAME_ATTRIBUTE = "OrderName";
	String SELLER_ORGANIZATION_CODE_ATTRIBUTE = "SellerOrganizationCode";
	String TAX_EXEMPT_FLAG_ATTRIBUTE = "TaxExemptFlag";
	
    // Order Extn Attributes    
     String EXTN_IS_DEPOSIT_AMOUNT_COLLECTED_ATTRIBUTE = "ExtnIsDepositAmountCollected";     
     String EXTN_DEPOSIT_AMOUNT_ATTRIBUTE = "ExtnDepositAmount";    
     String EXTN_HBC_ASSOCIATE_ID_ATTRIBUTE = "ExtnHBCAssociateID";    
     String EXTN_AMOUNT_COLLECTED_ATTRIBUTE = "ExtnAmountCollected";
     String EXTN_GIFT_REGISTRY_NUM_ATTRIBUTE = "ExtnGiftRegistryNumber";
     String EXTN_DEPOSIT_FLAG_ATTRIBUTE = "ExtnDepositFlag";
        
     // Order Line Attributes        
     String DELIVERY_METHOD_ATTRIBUTE = "DeliveryMethod";
     String FULFILLMENT_TYPE_ATTRIBUTE = "FulfillmentType";
     String ITEM_GROUP_CODE_ATTRIBUTE = "ItemGroupCode";
     String LINE_TYPE_ATTRIBUTE = "LineType";
     String LINE_STATUS_ATTRIBUTE = "LineStatus";
     String ORDER_QTY_ATTRIBUTE = "OrderQty";
     String PRIME_LINE_NO_ATTRIBUTE = "PrimeLineNo";
     String PROMISED_APPT_START_DATE = "PromisedApptStartDate";
     String PROMISED_APPT_END_DATE = "PromisedApptEndDate";
     String REQ_DELIVERY_DATE_ATTRIBUTE = "ReqDeliveryDate";    
     String SHIP_NODE_ATTRIBUTE = "ShipNode";    
     String SHIP_TO_ID_ATTRIBUTE = "ShipToID";    
     String SUB_LINE_NO_ATTRIBUTE = "SubLineNo";
     String IS_PRICE_LOCKED_ATTRIBUTE = "IsPriceLocked";
     String PICKABLE_FLAG_ATTRIBUTE = "PickableFlag";
     String REQ_SHIP_DATE_ATTRIBUTE = "ReqShipDate";
     String SHIP_TO_KEY_ATTRIBUTE = "ShipToKey";

     // Order Line Extn Attributes
            
     String EXTN_GIFT_REGISTRY_NO_ATTRIBUTE = "ExtnGiftRegistryNo";    
     String EXTN_GIFT_REGISTRY_LINE_NO_ATTRIBUTE = "ExtnGiftRegistryLineNo";    
     String EXTN_POS_ELIGIBLE_ATTRIBUTE = "ExtnPOSEligible";    
     String EXTN_POS_TXN_NUM_ATTRIBUTE = "ExtnPOSTxnNum";    
     String EXTN_POS_STORE_NUM_ATTRIBUTE = "ExtnPOSStoreNum";    
     String EXTN_POS_REG_NUM_ATTRIBUTE = "ExtnPOSRegNum";    
     String EXTN_POS_PROVINCE_ATTRIBUTE = "ExtnPOSProvince";    
     String EXTN_TAX_PROVINCE_ATTRIBUTE = "ExtnTaxProvince";    
     String EXTN_POS_TENDER_DT_ATTRIBUTE = "ExtnPOSTenderDT";    
     String EXTN_RESTOCKING_FEE_FLAG_ATTRIBUTE = "ExtnRestockingFeeFlag";    
     String EXTN_DC_DROP_OFF_FLAG_ATTRIBUTE = "ExtnDCdropoffFlag";    
     String EXTN_WARRANTY_SKU_ATTRIBUTE = "ExtnWarrantySKU";    
     String EXTN_IS_VENDOR_MODEL_ITEM_ATTRIBUTE = "ExtnIsVendorModelItem";    
     String EXTN_POND_ID_ATTRIBUTE = "ExtnPondID";    
     String EXTN_IS_POND_ATTRIBUTE = "ExtnIsPond";    
     String EXTN_SWING_BY_STORE_ATTRIBUTE = "ExtnSwingByStore";    
     String EXTN_IS_OPEN_BOX_ITEM_ATTRIBUTE = "ExtnIsOpenBoxItem";    
     String EXTN_IS_SWING_BY_ATTRIBUTE = "ExtnIsSwingBy";
     
     // DerivedFrom Attributes
     String DERIVED_FROM_DOCUMENT_TYPE_ATTRIBUTE = "DocumentType";
     String DERIVED_FROM_ENTERPRISE_CODE_ATTRIBUTE = "EnterpriseCode";
     String DERIVED_FROM_PRIME_LINE_NO_ATTRIBUTE = "PrimeLineNo";
     String DERIVED_FROM_SUB_LINE_NO_ATTRIBUTE = "SubLineNo";
    
     // Order Line Option Attributes
        
     String OPTION_DESCRIPTION_ATTRIBUTE = "OptionDescription";    
     String OPTION_ITEM_ID_ATTRIBUTE = "OptionItemID";    
     String OPTION_UOM_ATTRIBUTE = "OptionUOM";    
     String UNIT_PRICE_ATTRIBUTE = "UnitPrice";
        
     // Item Attributes
        
     String ITEM_DESC_ATTRIBUTE = "ItemDesc";    
     String ITEM_ID_ATTRIBUTE = "ItemID";    
     String ITEM_SHORT_DESC_ATTRIBUTE = "ItemShortDesc";    
     String PRODUCT_CLASS_ATTRIBUTE = "ProductClass";    
     String UNIT_COST_ATTRIBUTE = "UnitCost";    
     String UNIT_OF_MEASURE_ATTRIBUTE = "UnitOfMeasure";
     String ITEM_WEIGHT_ATTRIBUTE="ItemWeight";
     String ITEM_WEIGHT_UOM_ATTRIBUTE="ItemWeightUOM";
     String PRODUCT_LINE_ATTRIBUTE="ProductLine";
    
     // PersonInfo Attributes
        
     String ADDRESS_LINE_1_ATTRIBUTE = "AddressLine1";    
     String ADDRESS_LINE_2_ATTRIBUTE = "AddressLine2";    
     String ADDRESS_LINE_3_ATTRIBUTE = "AddressLine3";    
     String ADDRESS_LINE_4_ATTRIBUTE = "AddressLine4";    
     String ADDRESS_LINE_5_ATTRIBUTE = "AddressLine5";    
     String ADDRESS_LINE_6_ATTRIBUTE = "AddressLine6";    
     String CITY_ATTRIBUTE = "City";    
     String COUNTRY_ATTRIBUTE = "Country";    
     String DAY_PHONE_ATTRIBUTE = "DayPhone";    
     String EMAIL_ID_ATTRIBUTE = "EmailID";    
     String EVENING_FAX_NO_ATTRIBUTE = "EveningFaxNo";    
     String EVENING_PHONE_ATTRIBUTE = "EveningPhone";    
     String FIRST_NAME_ATTRIBUTE = "FirstName";    
     String LAST_NAME_ATTRIBUTE = "LastName";    
     String MIDDLE_NAME_ATTRIBUTE = "MiddleName";    
     String MOBILE_PHONE_ATTRIBUTE = "MobilePhone";    
     String OTHER_PHONE_ATTRIBUTE = "OtherPhone";    
     String STATE_ATTRIBUTE = "State";   
     String TITLE_ATTRIBUTE = "Title";    
     String ZIP_CODE_ATTRIBUTE = "ZipCode";

     // Line Price Info Attributes
        
     String TAX_EXEMPTION_CERTIFICATE_ATTRIBUTE = "TaxExemptionCertificate";    
     String TAXABLE_FLAG_ATTRIBUTE = "TaxableFlag";       
    //  String UNIT_PRICE = "UnitPrice";

     // Line Charge Attributes
        
     String CHARGE_CATEGORY_ATTRIBUTE = "ChargeCategory";    
     String CHARGE_NAME_ATTRIBUTE = "ChargeName";    
     String CHARGE_PER_LINE_ATTRIBUTE = "ChargePerLine";     
     String CHARGE_PER_UNIT_ATTRIBUTE = "ChargePerUnit";

     // Line Tax Attributes
        
     String TAX_ATTRIBUTE = "Tax";    
     String TAX_NAME_ATTRIBUTE = "TaxName";    
     String TAX_PERCENTAGE_ATTRIBUTE = "TaxPercentage";    
     
     // Order Line Relationship
     String RELATION_SHIP_TYPE_ATTRIBUTE = "RelationShipType";
     
     // Header Charge Attributes        
     String CHARGE_AMOUNT_ATTRIBUTE = "ChargeAmount";     
    
     // Header Tax Attributes     
}